package com.hzit.mmcb.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hzit.mmcb.core.enums.ReturnMethodEnum;
import com.hzit.mmcb.core.enums.TransTypeEnum;
import com.hzit.mmcb.core.hfb.FormHelper;
import com.hzit.mmcb.core.hfb.HfbConst;
import com.hzit.mmcb.core.hfb.RequestHelper;
import com.hzit.mmcb.core.pojo.dto.UserInfoDTO;
import com.hzit.mmcb.core.pojo.entity.TransFlow;
import com.hzit.mmcb.core.pojo.entity.UserAccount;
import com.hzit.mmcb.core.mapper.UserAccountMapper;
import com.hzit.mmcb.core.pojo.entity.UserInfo;
import com.hzit.mmcb.core.service.TransFlowService;
import com.hzit.mmcb.core.service.UserAccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzit.mmcb.core.service.UserInfoService;
import com.hzit.mmcb.core.utils.*;
import com.sun.xml.bind.v2.model.core.ID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 用户账户 服务实现类
 * </p>
 *
 * @author ljh
 * @since 2024-08-27
 */
@Service
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private TransFlowService transFlowService;
    //充值接口
    @Override
    public String commitCharge(BigDecimal chargeAmt, Long userId) {
        UserInfo userInfo = userInfoService.getById(userId);
        String chargeNo = LendNoUtils.getChargeNo();

        //生成表单
        Map<String,Object> map=new HashMap<>();
        map.put("agentId", HfbConst.AGENT_ID);
        map.put("agentBillNo",chargeNo);
        map.put("bindCode",userInfo.getBindCode());
        map.put("chargeAmt",chargeAmt);
        map.put("feeAmt",new BigDecimal(0));
        map.put("notifyUrl",HfbConst.RECHARGE_NOTIFY_URL);
        map.put("returnUrl",HfbConst.RECHARGE_RETURN_URL);
        map.put("timestamp", RequestHelper.getTimestamp());
        map.put("sign",RequestHelper.getSign(map));
        String formStr = FormHelper.buildForm(HfbConst.RECHARGE_URL, map);
        return formStr;
    }

    /**
     * 回调绑定信息
     * @param map
     * @return
     */
    @Override
    public String notifyAccount(Map<String, Object> map) {
        String bindCode = (String) map.get("bindCode");
        BigDecimal chargeAmt = new BigDecimal((String) map.get("chargeAmt"));
        String agentBillNO = (String) map.get("agentBillNo");
        UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getBindCode, bindCode));

        //幂等性校验
        TransFlow transFlowServiceOne = transFlowService.getOne(new LambdaQueryWrapper<TransFlow>().eq(TransFlow::getTransNo, agentBillNO));
        if (transFlowServiceOne!=null){
            System.out.println("---------------------触发了幂等性规则--------------------------");
            return "success";
        }
        //添加充值流水
        TransFlow transFlow = new TransFlow();
        transFlow.setUserId(userInfo.getId());
        transFlow.setUserName(userInfo.getName());
        transFlow.setTransNo(agentBillNO);
        transFlow.setTransType(TransTypeEnum.CHARGE.getIntegral());
        transFlow.setTransTypeName(TransTypeEnum.CHARGE.getMsg());
        transFlow.setTransAmount(chargeAmt);
        transFlow.setMemo("充值");
        transFlowService.save(transFlow);

        //修改账户余额
        UserAccount userAccount = this.getOne(new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, userInfo.getId()));
        userAccount.setAmount(userAccount.getAmount().add(chargeAmt));
        userAccount.setFreezeAmount(userAccount.getFreezeAmount().add(new BigDecimal(0)));
        this.updateById(userAccount);
        return "success";
    }

    /**
     * 查询用户余额
     * @param userId
     * @return
     */
    @Override
    public BigDecimal getAccount(Long userId) {
        UserAccount userAccount = this.getOne(new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, userId));

        return userAccount.getAmount();
    }

    /**
     * 计算预期收益
     * @param investAmount      投资金额
     * @param lendYearRate      年利率
     * @param period            投资期数
     * @param returnMethod      还款方式
     * @return
     */
    @Override
    public BigDecimal getInterestCount(BigDecimal investAmount, BigDecimal lendYearRate, Integer period, Integer returnMethod) {
        if (ReturnMethodEnum.ONE.getIntegral()==returnMethod){
            return Amount1Helper.getInterestCount(investAmount,lendYearRate,period);
        }
        if (ReturnMethodEnum.TWO.getIntegral()==returnMethod){
            return Amount2Helper.getInterestCount(investAmount,lendYearRate,period);
        }
        if (ReturnMethodEnum.THREE.getIntegral()==returnMethod){
            return Amount3Helper.getInterestCount(investAmount,lendYearRate,period);
        }
        if (ReturnMethodEnum.FOUR.getIntegral()==returnMethod){
            return Amount4Helper.getInterestCount(investAmount,lendYearRate,period);
        }
        return new BigDecimal(0);
    }

    @Override
    public String commitWithdraw(BigDecimal fetchAmt, Long userId) {
        UserInfo userInfo = userInfoService.getById(userId);
        Map<String,Object> paramMap=new HashMap<>();
        paramMap.put("agentId",HfbConst.AGENT_ID);
        paramMap.put("agentBillNo",LendNoUtils.getWithdrawNo());
        paramMap.put("bindCode",userInfo.getBindCode());
        paramMap.put("fetchAmt",fetchAmt);
        paramMap.put("feeAmt",new BigDecimal(0));
        paramMap.put("notifyUrl",HfbConst.WITHDRAW_NOTIFY_URL);
        paramMap.put("returnUrl",HfbConst.WITHDRAW_RETURN_URL);
        paramMap.put("timestamp",RequestHelper.getTimestamp());
        paramMap.put("sign",RequestHelper.getSign(paramMap));
        String formStr = FormHelper.buildForm(HfbConst.WITHDRAW_URL, paramMap);
        return formStr;
    }

    /**
     * 提现成功回调处理
     * @param map
     * @return
     */
    @Override
    public String notifyWithdraw(Map<String, Object> map) {
        String bindCode = (String) map.get("bindCode");
        BigDecimal fetchAmt = new BigDecimal((String) map.get("fetchAmt"));
        String agentBillNO = (String) map.get("agentBillNo");
        UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getBindCode, bindCode));

        //幂等性校验
        TransFlow transFlowServiceOne = transFlowService.getOne(new LambdaQueryWrapper<TransFlow>().eq(TransFlow::getTransNo, agentBillNO));
        if (transFlowServiceOne!=null){
            System.out.println("---------------------触发了幂等性规则--------------------------");
            return "success";
        }

        //添加流水记录
        TransFlow transFlow = new TransFlow();
        transFlow.setUserId(userInfo.getId());
        transFlow.setUserName(userInfo.getName());
        transFlow.setTransNo(agentBillNO);
        transFlow.setTransType(TransTypeEnum.WITHDRAW.getIntegral());
        transFlow.setTransTypeName(TransTypeEnum.WITHDRAW.getMsg());
        transFlow.setTransAmount(fetchAmt);
        transFlow.setMemo("提现");
        transFlowService.save(transFlow);

        //修改提现人账户
        UserAccount userAccount = this.getOne(new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, userInfo.getId()));
        userAccount.setAmount(userAccount.getAmount().subtract(fetchAmt));
        this.updateById(userAccount);
        return "success";
    }
}
